<template>
	<div class="jenkins-credential-container layout-padding">
		<el-card shadow="hover" class="layout-padding-auto">
			<div class="jenkins-credential-search mb15">
				<el-input
					size="default"
					v-model="state.searchForm.keyword"
					placeholder="请输入凭证ID或描述"
					style="max-width: 200px"
					clearable
				></el-input>
				<el-select
					v-model="state.searchForm.type"
					placeholder="凭证类型"
					clearable
					style="max-width: 150px"
					class="ml10"
				>
					<el-option label="用户名密码" value="usernamePassword"></el-option>
					<el-option label="SSH密钥" value="sshKey"></el-option>
					<el-option label="密钥文本" value="secretText"></el-option>
					<el-option label="证书" value="certificate"></el-option>
				</el-select>
				<el-button size="default" type="primary" @click="getTableData" class="ml10">
					<el-icon>
						<ele-Search />
					</el-icon>
					查询
				</el-button>
				<el-button size="default" type="success" class="ml10" @click="onOpenAddCredential('add')">
					<el-icon>
						<ele-Plus />
					</el-icon>
					新增凭证
				</el-button>
				<el-button
					size="default"
					type="danger"
					class="ml10"
					@click="onBatchDelete"
					:disabled="state.multipleSelection.length === 0"
				>
					<el-icon>
						<ele-Delete />
					</el-icon>
					批量删除
				</el-button>
			</div>
			<el-table
				:data="state.tableData.data"
				v-loading="state.tableData.loading"
				style="width: 100%"
				@selection-change="handleSelectionChange"
			>
				<el-table-column type="selection" width="55" />
				<el-table-column type="index" label="序号" width="60" />
				<el-table-column prop="credentialId" label="凭证ID" show-overflow-tooltip min-width="150">
					<template #default="scope">
						<span>{{ scope.row.credentialId }}</span>
						<el-button
							size="small"
							text
							type="primary"
							@click="copyToClipboard(scope.row.credentialId)"
							class="ml5"
						>
							<el-icon><ele-CopyDocument /></el-icon>
						</el-button>
					</template>
				</el-table-column>
				<el-table-column prop="description" label="描述" show-overflow-tooltip min-width="200"></el-table-column>
				<el-table-column prop="type" label="类型" width="120">
					<template #default="scope">
						<el-tag :type="getCredentialTypeTag(scope.row.type)">{{ getCredentialTypeName(scope.row.type) }}</el-tag>
					</template>
				</el-table-column>
				<el-table-column prop="scope" label="作用域" width="100">
					<template #default="scope">
						<el-tag :type="scope.row.scope === 'GLOBAL' ? 'success' : 'info'">{{ scope.row.scope }}</el-tag>
					</template>
				</el-table-column>
				<el-table-column prop="usageCount" label="使用次数" width="100"></el-table-column>
				<el-table-column prop="createdTime" label="创建时间" width="180" show-overflow-tooltip></el-table-column>
				<el-table-column label="操作" width="180" fixed="right">
					<template #default="scope">
						<el-button size="small" text type="primary" @click="onOpenEditCredential('edit', scope.row)">编辑</el-button>
						<el-button size="small" text type="primary" @click="onOpenDetailCredential(scope.row)">详情</el-button>
						<el-button size="small" text type="danger" @click="onRowDel(scope.row)">删除</el-button>
					</template>
				</el-table-column>
			</el-table>
			<el-pagination
				@size-change="onHandleSizeChange"
				@current-change="onHandleCurrentChange"
				class="mt15"
				:pager-count="5"
				:page-sizes="[10, 20, 30, 50]"
				v-model:current-page="state.tableData.param.page"
				background
				v-model:page-size="state.tableData.param.size"
				layout="total, sizes, prev, pager, next, jumper"
				:total="state.tableData.total"
			>
			</el-pagination>
		</el-card>
		<CredentialForm ref="credentialFormRef" @refresh="getTableData()" />
		<CredentialDetail ref="credentialDetailRef" />
	</div>
</template>

<script setup lang="ts" name="jenkinsCredential">
import { defineAsyncComponent, reactive, onMounted, ref } from 'vue';
import { ElMessageBox, ElMessage } from 'element-plus';
import { credentialApi, type CredentialItem } from '/@/api/jenkins/credential';

// 引入组件
const CredentialForm = defineAsyncComponent(() => import('./components/CredentialForm.vue'));
const CredentialDetail = defineAsyncComponent(() => import('./components/CredentialDetail.vue'));

// 定义变量内容
const credentialFormRef = ref();
const credentialDetailRef = ref();
const state = reactive<{
	searchForm: {
		keyword: string;
		type: string;
	};
	multipleSelection: CredentialItem[];
	tableData: {
		data: CredentialItem[];
		total: number;
		loading: boolean;
		param: {
			page: number;
			size: number;
		};
	};
}>({
	searchForm: {
		keyword: '',
		type: '',
	},
	multipleSelection: [],
	tableData: {
		data: [],
		total: 0,
		loading: false,
		param: {
			page: 1,
			size: 10,
		},
	},
});

// 初始化表格数据
const getTableData = () => {
	state.tableData.loading = true;
	const param = {
		keyword: state.searchForm.keyword,
		type: state.searchForm.type,
		...state.tableData.param,
	};
	credentialApi()
		.pageCredentials(param)
		.then((res) => {
			state.tableData.data = res.data.records;
			state.tableData.total = res.data.total;
			setTimeout(() => {
				state.tableData.loading = false;
			}, 500);
		})
		.catch(() => {
			state.tableData.loading = false;
		});
};

// 打开新增凭证弹窗
const onOpenAddCredential = (type: string) => {
	credentialFormRef.value.openDialog(type);
};

// 打开编辑凭证弹窗
const onOpenEditCredential = (type: string, row: CredentialItem) => {
	credentialFormRef.value.openDialog(type, row);
};

// 打开凭证详情弹窗
const onOpenDetailCredential = (row: CredentialItem) => {
	credentialDetailRef.value.openDialog(row);
};

// 删除凭证
const onRowDel = (row: CredentialItem) => {
	ElMessageBox.confirm(`此操作将永久删除凭证："${row.credentialId}"，是否继续?`, '提示', {
		confirmButtonText: '确认',
		cancelButtonText: '取消',
		type: 'warning',
	})
		.then(() => {
			credentialApi()
				.deleteCredential({ id: row.id })
				.then(() => {
					getTableData();
					ElMessage.success('删除成功');
				});
		})
		.catch(() => {});
};

// 批量删除
const onBatchDelete = () => {
	if (state.multipleSelection.length === 0) {
		ElMessage.warning('请选择要删除的凭证');
		return;
	}
	ElMessageBox.confirm(`此操作将永久删除选中的 ${state.multipleSelection.length} 个凭证，是否继续?`, '提示', {
		confirmButtonText: '确认',
		cancelButtonText: '取消',
		type: 'warning',
	})
		.then(() => {
			const ids = state.multipleSelection.map((item) => item.id);
			credentialApi()
				.batchDeleteCredentials({ ids })
				.then(() => {
					getTableData();
					ElMessage.success('批量删除成功');
					state.multipleSelection = [];
				});
		})
		.catch(() => {});
};

// 表格多选
const handleSelectionChange = (selection: CredentialItem[]) => {
	state.multipleSelection = selection;
};

// 复制到剪贴板
const copyToClipboard = async (text: string) => {
	try {
		await navigator.clipboard.writeText(text);
		ElMessage.success('复制成功');
	} catch (err) {
		ElMessage.error('复制失败');
	}
};

// 获取凭证类型名称
const getCredentialTypeName = (type: string) => {
	const typeMap: Record<string, string> = {
		usernamePassword: '用户名密码',
		sshKey: 'SSH密钥',
		secretText: '密钥文本',
		certificate: '证书',
	};
	return typeMap[type] || type;
};

// 获取凭证类型标签颜色
const getCredentialTypeTag = (type: string) => {
	const tagMap: Record<string, string> = {
		usernamePassword: 'primary',
		sshKey: 'success',
		secretText: 'warning',
		certificate: 'info',
	};
	return tagMap[type] || '';
};

// 分页改变
const onHandleSizeChange = (val: number) => {
	state.tableData.param.size = val;
	getTableData();
};

// 分页改变
const onHandleCurrentChange = (val: number) => {
	state.tableData.param.page = val;
	getTableData();
};

// 页面加载时
onMounted(() => {
	getTableData();
});
</script>

<style scoped lang="scss">
.jenkins-credential-container {
	:deep(.el-card__body) {
		display: flex;
		flex-direction: column;
		flex: 1;
		overflow: auto;

		.el-table {
			flex: 1;
		}
	}
}

.jenkins-credential-search {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 10px;
}
</style>